package com.cyt.web.controller.sys;

import com.cyt.base.enums.BusinessType;
import com.cyt.base.enums.OperatorType;
import com.cyt.base.model.dto.ReturnResult;
import com.cyt.base.util.BaseConstant;
import com.cyt.base.util.ErrorCode;
import com.cyt.sys.aspect.BaseLog;
import com.cyt.sys.model.dto.BaseUserOnline;
import com.cyt.sys.model.po.SysFile;
import com.cyt.sys.model.po.SysUser;
import com.cyt.sys.model.po.SysUserRole;
import com.cyt.sys.model.vo.SysFileVo;
import com.cyt.sys.model.vo.SysOrgUserVo;
import com.cyt.sys.model.vo.SysRoleVo;
import com.cyt.sys.model.vo.SysUserVo;
import com.cyt.sys.service.*;
import com.cyt.work.wb.model.po.WbCheckCode;
import com.cyt.work.wb.service.WbCheckCodeService;
import com.cyt.wx.model.po.WxApply;
import com.cyt.wx.model.vo.WxAccountVo;
import com.cyt.wx.model.vo.WxApplyVo;
import com.cyt.wx.service.WxAccountService;
import com.cyt.wx.service.WxApplyService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 菜单控制层
 *
 * @author shengQiang yu
 * @date 2019-04-24 16:10
 */
@RestController
public class SysUserController extends SysBaseController {

    @Resource
    private SessionDAO sessionDAO;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysFileService sysFileService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysUserRoleService sysUserRoleService;
    @Resource
    private SysOrgUserService sysOrgUserService;
    @Resource
    private WbCheckCodeService wbCheckCodeService;
    @Resource
    private WxAccountService wxAccountService;
    @Resource
    private WxApplyService wxApplyService;

    /**
     * 用户模块统一跳转处理
     *
     * @param model 对象
     * @return Model
     * @author shengQiang yu
     * @date 2019-04-24 9:36
     */
    @RequestMapping("/sys/user/*")
    public Model goPage(Model model) {
        return model;
    }

    /**
     * 分页查询
     *
     * @param sysUserVo 对象
     * @param page      当前页面
     * @param limit     页面数量
     * @return ReturnResult 对象
     * @author liufu zhu
     * @date 2018-11-29 15:43
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "分页查询", businessType = BusinessType.GET, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/page", method = RequestMethod.POST)
    public ReturnResult page(SysUserVo sysUserVo, int limit, int page) {
        return sysUserService.pageListLeftRoleAndOrg(sysUserVo, limit, page);
    }


    /**
     * 跳转保存/更新页面
     *
     * @param id 角色id
     * @return ReturnResult 对象
     * @author liufu zhu
     * @date 2018-11-29 15:43
     */
    @RequestMapping(value = "/sysUser/getAddOrEdit", method = RequestMethod.GET)
    public ModelAndView getAddOrEdit(String id) {
        ModelAndView view = new ModelAndView("/sys/user/userEdit");
        //用户信息
        SysUser sysUser = null;
        if (StringUtils.isNotBlank(id)) {
            sysUser = sysUserService.selectByPrimaryKey(id);
            if (StringUtils.isNotBlank(sysUser.getHeadLogo())) {
                SysFile sysFile = sysFileService.selectOneByExample(new SysFileVo(sysUser.getHeadLogo()));
                if (sysFile != null) {
                    sysUser.setSysFile(sysFile);
                }
            }
            view.addObject(sysUser);
        }
        //用户角色信息
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setUserId(id);
        view.addObject("urList", sysUserRoleService.select(sysUserRole));
        //用户部门信息
        if (StringUtils.isNotBlank(id)) {
            SysOrgUserVo sysOrgUserVo = new SysOrgUserVo();
            sysOrgUserVo.setUserId(id);
            view.addObject("orgList", sysOrgUserService.listLeftOrg(sysOrgUserVo));
        }
        //所有角色信息
        view.addObject("list", sysRoleService.listExample(new SysRoleVo()));
        //通用公众号
        if (sysUser == null) {
            view.addObject("isAccount", "0");
            WxAccountVo wxAccountVo = new WxAccountVo();
            wxAccountVo.setAccountType(String.valueOf(1));
            view.addObject(wxAccountService.listExample(wxAccountVo));
        } else {
            if (StringUtils.isBlank(sysUser.getAccountId())) {
                WxApplyVo wxApplyVo = new WxApplyVo();
                wxApplyVo.setUserId(sysUser.getId());
                List<WxApply> wxApplyList = wxApplyService.listExample(wxApplyVo);
                wxApplyList.removeIf(wxApply -> StringUtils.isBlank(wxApply.getAccountId()));
                if (CollectionUtils.isEmpty(wxApplyList)) {
                    view.addObject("isAccount", "0");
                    WxAccountVo wxAccountVo = new WxAccountVo();
                    wxAccountVo.setAccountType(String.valueOf(1));
                    view.addObject(wxAccountService.listExample(wxAccountVo));
                } else {
                    view.addObject("isAccount", "2");
                }
            } else {
                view.addObject("isAccount", "1");
                WxAccountVo wxAccountVo = new WxAccountVo();
                wxAccountVo.setId(sysUser.getAccountId());
                view.addObject(wxAccountService.listExample(wxAccountVo));
            }
        }
        return view;
    }

    /**
     * 保存/更新用户
     *
     * @return ReturnResult
     * @author liufu zhu
     * @date 2019/4/8 15:01
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "保存/更新用户", businessType = BusinessType.INSERT, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/addOrUpdate", method = RequestMethod.POST)
    public ReturnResult addOrUpdate(HttpServletRequest request, SysUserVo sysUserVo) {
        return sysUserService.addOrUpdate(sysUserVo, acceptCurrentUser(request));
    }

    /**
     * 删除用户
     *
     * @return ReturnResult
     * @author liufu zhu
     * @date 2019/4/8 15:01
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "删除用户", businessType = BusinessType.DELETE, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/removeByIds", method = RequestMethod.GET)
    public ReturnResult removeByIds(HttpServletRequest request, String id) {
        return sysUserService.removeByIds(id, acceptCurrentUser(request));
    }

    /**
     * 获取组织机构树
     *
     * @return ReturnResult
     * @author shengQiang yu
     * @date 2019/4/8 15:01
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "用户树", businessType = BusinessType.GET, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/dTreeList", method = RequestMethod.POST)
    public ReturnResult dTreeList(SysUserVo sysUserVo) {
        return sysUserService.dTreeList(sysUserVo);
    }

    /**
     * 增加或修改角色的用户
     *
     * @return ReturnResult
     * @author changZheng hou
     * @date 2019/4/8 16:50
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "用户树", businessType = BusinessType.GET, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/UpdateUser", method = RequestMethod.POST)
    public ReturnResult addOrUpdate(String roleId, String ruleIds) {
        return sysUserRoleService.UpdateUser(roleId, ruleIds);
    }

    /**
     * 获取组织机构树
     *
     * @author YuShengQiang
     * @date 2018-12-05 16:17
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "数据导出", businessType = BusinessType.EXPORT, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/exportExecl", method = RequestMethod.POST)
    public void exportExecl(HttpServletResponse response, SysUserVo sysUserVo) {
        sysUserService.exportExecl(response, sysUserVo);
    }

    /**
     * 数据导入
     *
     * @author YuShengQiang
     * @date 2018-12-05 16:17
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "数据导入", businessType = BusinessType.EXPORT, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/importExecl", method = RequestMethod.POST)
    public ReturnResult importExecl(MultipartFile file, HttpServletRequest request, String catalog, String update) {
        return sysUserService.importExecl(file, request, catalog, update);
    }

    /**
     * 在线用户分页查询
     *
     * @param limit 页面大小
     * @param page  当前页
     * @author congcong tao
     * @date 2019/3/11 8:39
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "在线用户分页", businessType = BusinessType.GET, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/pageOnline", method = RequestMethod.POST)
    public ReturnResult pageOnline(int limit, int page) {
        Collection<Session> sessionList = sessionDAO.getActiveSessions();
        List<BaseUserOnline> list = new ArrayList<>();
        BaseUserOnline userOnline;
        for (Session s : sessionList) {
            userOnline = new BaseUserOnline();
            userOnline.setSessionId((String) s.getId());
            userOnline.setIpAddress(s.getHost());
            userOnline.setStartTimestamp(s.getStartTimestamp());
            userOnline.setLastAccessTime(s.getLastAccessTime());
            Object obj = s.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (obj != null) {
                SimplePrincipalCollection spc = (SimplePrincipalCollection) obj;
                if (spc.getPrimaryPrincipal() != null) {
                    // 转成User
                    SysUser u = (SysUser) spc.getPrimaryPrincipal();
                    userOnline.setLoginName(u.getLoginName());
                    userOnline.setUserName(u.getName());
                }
            } else {
                continue;
            }
            // 装成list，好做分页查询功能
            list.add(userOnline);
        }
        long startL = (page - 1) * limit;
        long endL = startL + limit;
        int start = (int) startL;
        int end = (int) endL;
        List<BaseUserOnline> records = list.subList(start, end > list.size() ? list.size() : end);
        return new ReturnResult(records, sessionList.size(), false);
    }

    /**
     * 踢出在线用户
     *
     * @param sessionId 会话ID
     * @author congcong tao
     * @date 2019/3/11 9:23
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "踢出在线用户", businessType = BusinessType.DELETE, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/deleteOnline", method = RequestMethod.GET)
    public ReturnResult deleteOnline(String sessionId) {
        Session session = sessionDAO.readSession(sessionId);
        if (session != null) {
            sessionDAO.delete(session);
        }
        return new ReturnResult();
    }

    /**
     * 更新用户信息
     *
     * @param request   请求对象
     * @param sysUserVo 参数传入对象
     * @return ReturnResult
     * @author rong yuan
     * @date 2019-8-20 16:29
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "更新用户信息", businessType = BusinessType.UPDATE, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/update", method = RequestMethod.POST)
    public ReturnResult update(HttpServletRequest request, SysUserVo sysUserVo) {
        return sysUserService.update(request, sysUserVo);
    }

    /**
     * 注册用户
     *
     * @param request
     * @param sysUserVo
     * @author congcong tao
     * @date 2019/12/30 9:45
     */
    @BaseLog(module = "系统模块", classz = "用户管理", methods = "用户注册", businessType = BusinessType.UPDATE, operatorType = OperatorType.MANAGE)
    @RequestMapping(value = "/sysUser/register", method = RequestMethod.POST)
    public ReturnResult register(HttpServletRequest request, SysUserVo sysUserVo, String code) {
        ReturnResult returnEntity = wbCheckCodeService.checkCode(sysUserVo.getPhone(), code);
        if (returnEntity.getCode() != ErrorCode.CODE_0) {
            return returnEntity;
        }
        WbCheckCode wbCheckCode = (WbCheckCode) returnEntity.getData();
        // 注册用户
        ReturnResult registerResult = sysUserService.register(request, sysUserVo);
        // 在注册成功及获取验证码存在后使用
        if (registerResult.getCode() == ErrorCode.CODE_0 && wbCheckCode != null) {
            wbCheckCode.setUseTime(new Date());
            wbCheckCode.setUseStatus(BaseConstant.BASE_USE_STATUS_YSY);
            wbCheckCodeService.updateByPrimaryKey(wbCheckCode);
        }
        return registerResult;
    }
}